package org.jeecg.modules.simulator.model.line.station.strategy;

import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.simulator.model.MetroTrain;
import org.jeecg.modules.simulator.model.OffTrainNumRange;
import org.jeecg.modules.simulator.model.line.Line;
import org.jeecg.modules.simulator.model.line.station.station.Station;
import org.jeecg.modules.simulator.model.line.station.station.TransferStation;
import org.jeecg.modules.simulator.model.person.Person;

import lombok.Getter;
import lombok.Setter;

import java.time.LocalTime;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jeecg.modules.simulator.model.person.path.PersonState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * @program: gp2
 * @description:
 * @author: renzhg
 * @create: 2024-09-10 13:15
 **/

@Slf4j
public class NormalOffTrainStrategy implements ITrainStrategy{
    private static final Logger logger = LoggerFactory.getLogger(NormalOffTrainStrategy.class);


    @Setter
    @Getter
    Map<String, TransferStation> transferNameStationMap = new HashMap<>();

//    @Setter
//    @Getter
//    Map<String, TransferStation> transferStationMap = new HashMap<>();


    public NormalOffTrainStrategy(Map<String, Line> directionMap, Map<String, TransferStation> transferNameStationMap){
        this.directionMap=directionMap;
        this.transferNameStationMap=transferNameStationMap;
    }
    private Map<String, Line> directionMap=new HashMap<>();


    @Override
    public boolean trainExchange(MetroTrain metroTrain,
                                 Map<String, OffTrainNumRange> offTrainNumRangeMap,
                                 Map<String, Station> stationNameMap ,
                                 Station station,
                                 LocalTime now) {
        boolean retboo = true;
        OffTrainStrategy nomalOffTrain = new NomalOffTrainImpl(transferNameStationMap);



        //下车
        retboo = nomalOffTrain.offTrain(metroTrain, station,offTrainNumRangeMap,stationNameMap,now);
//        上车
        takeTrain(metroTrain, station);
        int personCount=metroTrain.countTotalPersons();
//        logger.debug("-------------当前列车人数："+personCount+"人");
        return retboo;
    }


//region 上车

    /**
     * @description: 找出站内候车客流，挨个上车
     * @author: renzhg
     * @date: 2024/9/10 13:22
     **/
    private void takeTrain(MetroTrain metroTrain, Station station) {


        Map<String, List<Person>> waitingMap = station.getWaitingPersonMap();
        if(!waitingMap.isEmpty()){
            System.out.println("takeTrain  Action");
        }
        Map<String, List<Person>> resultMap1 = new HashMap<>();
        String lineid = station.getLine();
        Line line=directionMap.get(lineid);
        takeTrainAction(metroTrain, waitingMap, resultMap1,line);
        resultMap1.forEach((key, value) -> {
            waitingMap.remove(key);
        });
    }

    private void takeTrainAction(MetroTrain metroTrain,
                                 Map<String, List<Person>> waitingMap,
                                 Map<String, List<Person>> resultMap1,
                                 Line line) {
        if(!waitingMap.isEmpty()){
            System.out.println("takeTrainAction  Action");
        }
//        logger.debug("将要上车的人数："+waitingMap.size()+"人");
        waitingMap.forEach((key, value) -> {
            Boolean persionIsUp = decisionDir(key.split("-")[0], key.split("-")[1], line);
            if(persionIsUp==null) {
                return;
            }
            //判断上下行方向是否一致
            if (metroTrain.getIsRuningUp() == persionIsUp) {
                if (metroTrain.recordOffTrain(value.size())) {
                    for(Person person:value){
                        person.setPersonState(PersonState.inTrain);
                    }
                    resultMap1.put(key, value);
                    metroTrain.addPassengerFlow(key, value);
                }
            }
        });
    }

    /**
     * @description: 方向判断，根据在这个线路上下轨道，判断这两个站点的方向是否与上行相反或一致，
     * ，然后在判断这个列车的方向是否与这个方向一致
     * @author: renzhg
     * @date: 2024/9/10 14:52
     * @param:
     * @param: oStationName
     * @param: nextNodeName
     * @return:
     * @return: boolean
     **/
    private Boolean decisionDir(String oStationName, String nextNodeName, Line line) {

        Integer fromUpIndex = line.getUpOrbitPath().getPointIndex(oStationName);
        if(fromUpIndex==null){
            return null;
        }

        Integer toUpIndex = line.getUpOrbitPath().getPointIndex(nextNodeName);
        if(toUpIndex==null){
            return null;
        }
        if (fromUpIndex < toUpIndex) {
            return true;
        } else {
            return false;
        }
    }

    //endregion


//region 下车





}
